package models;

import java.util.*;

import android.text.format.Time;

/**
 * 
 * Represents a Schedule of Tasks with a predetermined starting and ending Time.
 * Paraeter checking for setting start/end times are handled by com.std.getstuffdone/StartEndTimeEntry.java
 * 
 * @author Ajay Menon, Richard Pan
 *
 */

public class Schedule {
    private Map<Long, Task> taskCollection;
    private List<Task> taskList;
    private Time startTime;
    private Time endTime;

    /**
     * Constructor for Schedule
     * @param taskCollection Map containing task IDs that point to Tasks 
     * @param startTime Start time for the day's schedule
     * @param endTime End time for the day's schedule
     * 
     * @throws IllegalArgumentException if any parameters are null.
     */
    public Schedule (Map<Long, Task> taskCollection, Time startTime, Time endTime) {
        this(taskCollection, new ArrayList<Task>(), startTime, endTime);
    }
    
    /**
     * Second constructor for Schedule, taking a given task list into account
     * @param taskCollection Map containing task IDs that point to Tasks 
     * @param taskList List containing the tasks in order they are scheduled
     * @param startTime Start time for the day's schedule
     * @param endTime End time for the day's schedule
     * 
     * @throws IllegalArgumentException if any parameters are null.
     */
    public Schedule (Map<Long, Task> taskCollection, List<Task> taskList, Time startTime, Time endTime) {
    	if (taskCollection == null || taskList == null || startTime == null || endTime == null || startTime.after(endTime)) {
    		throw new IllegalArgumentException();
    	}
        this.taskCollection = taskCollection;
        this.taskList = taskList;
        this.startTime = startTime;
        this.endTime = endTime;
    }

    /**
     * Takes the id for a task and sets its completed state
     * @param id Task ID
     * @param status boolean flag representing task completion
     */
    public void setCompleted(long id, boolean completed) {
        Task task = this.taskCollection.get(id);
        if (task != null) {
            task.setCompleted(completed);
            this.taskCollection.put(id, task);
        }
    }
    
    /**
     * Takes a new task and inserts it into the collection
     * @param task Task to be inserted
     */
    public void addTask(Task task) {
    	taskCollection.put(task.getID(), task);
    }
    
    /**
     * Removes the specified task from the collection
     * @param id ID of the task
     */
    public void removeTask(long id) {
    	taskCollection.remove(id);
    }
    
    /**
     * Takes the id of a task and returns the Task object corresponding to it
     * @param id ID of the task
     * @return Task object corresponding to the task ID
     */
    public Task getTask(long id) {
    	return taskCollection.get(id);
    }
    
    /**
     * Removes all tasks from the collection
     */
    public void clearAllTasks() {
    	taskCollection.clear();
    }
    
    /**
     * Gets the start time for the schedule
     *
     * @return startTime Schedule's start time.
    */
    public Time getStartTime() {
    	return new Time(this.startTime);
    }
    
    /**
     * Gets the end time for the schedule
     *
     * @return endTime Schedule's ending time.
    */
    public Time getEndTime() {
    	return new Time(this.endTime);
    }
    
    /**
     * Sets the start time for the schedule.
     *
     * @param newStartTime new starting time for the schedule.
    */
    public void setStartTime(Time newStartTime) {
    	startTime.set(newStartTime);
    }

    /**
     * Sets the end time for the schedule
     *
     * @param newEndTime new ending time for the schedule.
    */
    public void setEndTime(Time newEndTime) {
        endTime.set(newEndTime);
    }

    /**
     * Sets the starting and ending time for the schedule.
     *
     * @param newStartTime new starting time for the schedule.
     * @param newEndTime new ending time for the schedule.
    */
    public void setStartEndTime(Time newStartTime, Time newEndTime) {
        setStartTime(newStartTime);
        setEndTime(newEndTime);
    }
    
    /**
     * Gets a list view of the tasks.
     * 
     * @returns the original schedule (before modifications) of the schedule
     * in a list sorted by start times.
     */
    public List<Task> getInitialListView() {
    	return taskList;
    }
    
    /**
     * Gets a collection of tasks.
     * @return a Collection<Task> representation of the Tasks stored in the schedule.
     */
    public Collection<Task> getTasks() {
    	return taskCollection.values();
    }
}
